package com.kanshu.service.impl;

import com.kanshu.constant.DownLoadType;
import com.kanshu.constant.ListType;
import com.kanshu.constant.StatusType;
import com.kanshu.constant.UpLoadTpye;
import com.kanshu.model.SocketUser;
import com.kanshu.service.MenuService;
import com.kanshu.service.NovelService;

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/**
 * @author GAIst
 * ClassName NovelServiceImpl.java
 * From
 * Description TODO
 * createTime 2024年12月20日14:32:26
 */
public class NovelServiceImpl implements NovelService {
    private static final ListType LISTTYPE = new ListType();
    private static MenuService menuService = new MenuServiceImpl();
    private static String msgToService = "";
    private static SocketUser socket;
    private static int pageNum;
    private static StatusType statusType = new StatusType();
    private static DownLoadType downLoadType = new DownLoadType();
    private static UpLoadTpye upLoadTpye = new UpLoadTpye();

    static {
        try {
            socket = new SocketUser();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 显示小说菜单并处理用户选择
     * 根据用户选择的类型显示相应的武侠或言情小说列表，并允许用户选择具体操作
     *
     * @param sca  用于获取用户输入的Scanner对象
     * @param type 小说类型，可以是"武侠"、"wuxia"、"言情"或"yanqing"
     * @return 返回一个布尔值，表示菜单操作是否成功
     * @throws IOException 如果在发送类型信息到服务器时发生I/O错误
     */
    @Override
    public boolean novelMenu(Scanner sca, String type) throws IOException {
        // 根据类型显示相应的欢迎信息
        if (type.equals(statusType.getCHWUXIA()) || type.equals(statusType.getENWUXIA())) {
            System.out.println(String.format(LISTTYPE.getOUTPUT_SIGN_BEGINLINE(), statusType.getCHWUXIA()));
        } else if (type.equals(statusType.getCHYANQING()) || type.equals(statusType.getENYANQING())) {
            System.out.println(String.format(LISTTYPE.getOUTPUT_SIGN_BEGINLINE(), statusType.getCHYANQING()));
        }

        // 显示菜单头部信息
        System.out.println(LISTTYPE.getOUTPUT_SIGN_HEAD());

        // 向服务器发送用户选择的小说类型
        typeChoose(type);

        // 显示菜单尾部信息
        System.out.println(LISTTYPE.getOUTPUT_SIGN_ENDLINE());

        // 提示用户进行选择
        System.out.println(LISTTYPE.getOUTPUT_TEXT_READDOWN());
        String choice = sca.nextLine();

        // 根据用户选择进行不同操作
        if (choice == statusType.getZERO() || choice.equals(statusType.getZERO())) {
            // 用户选择返回上一级菜单
            menuService.menu(sca, type);
        } else if (choice == statusType.getNEGATIVE_ONTE() || choice.equals(statusType.getNEGATIVE_ONTE())) {
            // 用户选择了一个未定义的操作，预留扩展位置
            //TODO
            upLoadNovel(sca, type);
        } else {
            // 用户选择了一个具体的小说进行阅读或下载
            // 将中文类型转换为英文类型以统一处理
            type = typeChToEn(type);

            // 调用方法处理用户的阅读或下载请求
            readAndDownload(sca, type, choice);
        }

        // 返回成功状态
        return true;
    }

    /**
     * 根据用户输入读取小说或下载小说
     *
     * @param sca   输入流，用于接收用户输入
     * @param type  小说类型
     * @param index 小说索引，用于标识特定的小说
     * @throws IOException 如果与服务器的通信中发生I/O错误
     */
    public void readAndDownload(Scanner sca, String type, String index) throws IOException {
        // 显示菜单功能
        System.out.println(LISTTYPE.getMENU_FUNCTION());
        // 接收用户的选择
        String choice = sca.nextLine();
        // 根据用户选择执行不同的操作
        switch (choice) {
            case "0":
                // 返回上一级菜单
                novelMenu(sca, type);
                break;
            case "1":
                // 重置页数为1
                pageNum = 1;
                // 根据小说类型修改type变量的值，以便与服务器通信
                type = typeChToEn(type);

                // 构造消息发送给服务器，请求读取小说
                msgToService = statusType.getREAD_NOVEL() + index + statusType.getCOMMA() + type;
                try {
                    // 发送消息给服务器
                    socket.send(msgToService);
                } catch (IOException e) {
                    // 如果发生I/O错误，抛出运行时异常
                    throw new RuntimeException(e);
                }
                // 接收用户进一步的选择
                choice = sca.nextLine();
                // 根据用户选择执行读取小说或下载小说的操作
                switch (choice) {
                    case "1":
                        // 读取小说
                        readNovel(sca, type, index);
                        break;
                    case "2":
                        // 下载小说
                        downloadNovel(sca, type, index);
                        break;
                    default:
                        // 如果输入无效，提示用户
                        System.out.println(LISTTYPE.getOUTPUT_TEXT_INVALIDINPUT());
                        break;
                }
                break;
            case "2":
                // 构造消息发送给服务器，请求下载小说
                msgToService = statusType.getDOWNLOAD_NOVEL() + index + statusType.getCOMMA() + type;
                try {
                    // 发送消息给服务器并接收下载的小说内容，然后保存到文件
                    saveFile((String) socket.downloadSend(msgToService));
                } catch (IOException e) {
                    // 如果发生I/O错误，抛出运行时异常
                    throw new RuntimeException(e);
                }
                break;
            default:
                // 如果输入无效，提示用户
                System.out.println(LISTTYPE.getOUTPUT_TEXT_INVALIDINPUT());
                break;
        }
    }

    /**
     * 下载小说功能方法
     *
     * @param sca   Scanner对象，用于用户输入交互，此处未使用
     * @param type  小说类型，用于指定下载的小说类别
     * @param index 小说索引，用于指定具体下载的小说
     */
    private void downloadNovel(Scanner sca, String type, String index) {
        // 构建下载小说的请求消息
        msgToService = statusType.getDOWNLOAD_NOVEL() + index + statusType.getCOMMA() + type;
        try {
            // 发送下载请求到服务端
            // 根据实际情况处理返回的数据
            String response = (String) socket.downloadSend(msgToService);
            // 处理响应，例如保存文件到本地
            saveFile(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将小说内容保存到文件中
     * 此方法首先定义了文件的保存路径和名称，然后检查文件是否已存在
     * 如果文件已存在，为了避免覆盖，会使用当前时间戳重命名文件
     * 最后，将小说内容写入文件
     *
     * @param fileContent 小说内容，将被写入文件
     */
    private void saveFile(String fileContent) {
        // 定义文件的基本路径和名称
        String basePath = statusType.getBASEPATH();
        String fileName = statusType.getFILENAME();
        String fullPath = basePath + fileName;

        // 检查文件是否存在
        Path path = Paths.get(fullPath);
        if (Files.exists(path)) {
            // 文件存在，生成一个新的文件名
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String timestamp = dateFormat.format(new Date());
            fileName = statusType.getCHANGE_FILENAME(timestamp);
            fullPath = basePath + fileName;
        }

        // 创建文件并写入内容
        try (FileWriter fileWriter = new FileWriter(fullPath)) {
            fileWriter.write(fileContent);
            System.out.println(downLoadType.getOUTPUT_TEXT_DOWNLOADSUCCESS(basePath, fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 根据用户选择读取小说章节
     *
     * @param sca   Scanner对象，用于从控制台获取用户输入
     * @param type  小说类型字符串，用于确定小说类别
     * @param index 小说索引字符串，用于确定具体小说
     * @throws IOException 如果与服务端通信发生错误
     */
    private void readNovel(Scanner sca, String type, String index) throws IOException {
        // 根据当前页数构建发送给服务端的消息
        if (pageNum != 1) {
            msgToService = statusType.getREAD_NOVEL_ALL() + index + statusType.getCOMMA()
                    + type + statusType.getCOMMA() + pageNum;
        } else {
            msgToService = statusType.getREAD_NOVEL_FRIST() + index + statusType.getCOMMA() + type + statusType.getCOMMA_ONE();
        }
        pageNum += 1;
        // 发送消息给服务端请求小说内容
        socket.send(msgToService);
        // 获取用户的选择
        String choice = sca.nextLine();
        // 根据用户选择执行对应操作
        switch (choice) {
            case "1":
                // 用户选择继续阅读，递归调用本方法
                readNovel(sca, type, index);
                break;
            case "2":
                // 用户选择返回菜单，调用菜单服务
                menuService.menu(sca, type);
                break;
            default:
                // 用户输入无效，提示错误信息
                System.out.println(LISTTYPE.getOUTPUT_TEXT_INVALIDINPUT());
                break;
        }
    }

    /**
     * 根据输入的类型选择对应的类型发送
     * 此方法旨在处理不同类型的选择与发送逻辑
     * 它根据输入的类型，决定发送哪种类型的状态信息
     *
     * @param type 输入的类型，用于决定发送哪种类型的状态信息
     * @throws IOException 如果发送操作失败，抛出此异常
     */
    private void typeChoose(String type) throws IOException {
        // 当输入类型为中文或英文的“武侠”时，发送英文的“武侠”
        if (type.equals(statusType.getCHWUXIA()) || type.equals(statusType.getENWUXIA())) {
            socket.send(statusType.getENWUXIA());
            // 当输入类型为中文或英文的“言情”时，发送英文的“言情”
        } else if (type.equals(statusType.getCHYANQING()) || type.equals(statusType.getENYANQING())) {
            socket.send(statusType.getENYANQING());
        }
    }

    /**
     * 将类型从中文转换为英文
     * 此方法根据输入的中文类型，将其转换为相应的英文类型
     * 如果输入的类型不是预定义的中文类型，则返回原始输入字符串
     *
     * @param type 中文类型字符串，表示当前的状态类型
     * @return 英文类型字符串，如果输入不是预定义的中文类型，则返回原始输入
     */
    private String typeChToEn(String type) {
        // 如果输入类型是“武侠”，则转换为对应的英文“WUXIA”
        if (type.equals(statusType.getCHWUXIA())) {
            type = statusType.getENWUXIA();
            // 如果输入类型是“言情”，则转换为对应的英文“YANQING”
        } else if (type.equals(statusType.getCHYANQING())) {
            type = statusType.getENYANQING();
        }
        // 返回转换后的类型，如果没有匹配到预定义的中文类型，则返回原始输入
        return type;
    }

    /**
     * 上传小说
     *
     * @param sca  Scanner对象，用于从控制台获取用户输入
     * @param type type 小说类型，用于告诉服务端小说类型，用于确定上传小说的类别
     * @throws IOException
     */
    private void upLoadNovel(Scanner sca, String type) throws IOException {
        // 将输入的中文类型转换为对应的英文类型
        type = typeChToEn(type);
        // 创建一个StringBuilder对象，用于构建上传信息
        // 字符串内容为1.上传小说2.小说类型3.小说名称4.小说作者5.小说简介6.小说路径中间采用*来进行分割
        StringBuilder stringBuilder = new StringBuilder(statusType.getUPLOAD_NOVEL() + type + statusType.getSTAR());
        //提示输入小说名称
        System.out.print(upLoadTpye.getOUTPUT_INPUT_NAME());
        stringBuilder.append(sca.nextLine() + statusType.getSTAR());
        //提示输入小说作者
        System.out.print(upLoadTpye.getOUTPUT_INPUT_AUTHOR());
        stringBuilder.append(sca.nextLine() + statusType.getSTAR());
        //提示输入小说简介
        System.out.print(upLoadTpye.getOUTPUT_INPUT_DESC());
        stringBuilder.append(sca.nextLine() + statusType.getSTAR());
        //提示输入小说路径
        System.out.print(upLoadTpye.getOUTPUT_INPUT_PATH());
        stringBuilder.append(sca.nextLine());

        //将所有信息发送给服务端 TODO返回消息判断
        String result = (String) socket.send(stringBuilder.toString());
        if (result.equals(upLoadTpye.getOUTPUT_TEXT_REUPLOAD())) {
            System.out.println(upLoadTpye.getOUTPUT_TEXT_REUPLOAD());
        }
    }


}
